/**
 * Copyright 2011 Honeywell Federal Manufacturing & Technologies, LLC. This material was produced under U.S. Government
 * contract DE-ACO4-01AL66850, Honeywell Federal Manufacturing & Technologies, LLC, (FM&T) with the U. S. Department of
 * Energy for the operation of the Kansas City Plant . The U.S. Government has rights to use, reproduce, and distribute
 * this software.  NEITHER THE GOVERNMENT NOR Honeywell Federal Manufacturing & Technologies, LLC, MAKES ANY WARRANTY,
 * EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE.  If software is modified to produce
 * derivative works, such modified software should be clearly marked, so as not to confuse it with the version available
 * from FM&T.
 *
 * Additionally, this program is free software; you can redistribute it and/or modify it under the terms of the GNU
 * General Public License Version 3 published by the Free Software Foundation. Accordingly, this program is distributed in
 * the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with this library.
 * If not, see http://www.gnu.org/licenses/.
 */
package org.braintrain.services;

import com.kcp.ko.authentication.domain.AuthenticatableUser;
import com.kcp.ko.fmtnmlib.service.dao.HibernatePersistenceDAO;
import org.apache.tapestry.services.DataSqueezer;
import org.braintrain.domain.*;
import org.braintrain.services.event.SuccessTestCompletion;
import org.braintrain.services.util.DOMContentParser;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.w3c.tidy.Tidy;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Set;

public class ContentServiceImpl implements ContentService, ApplicationContextAware {
    
    private HibernatePersistenceDAO genericDAO;
    private MediaService mediaService;
    private ApplicationContext applicationContext;



    /**
     * Grade the current test after the test has been submitted from the user.
     * Actions:
     * 1. Correct test (see Test.gradeTest())
     * 2. Save the answers given to the answer log (right or wrong)
     * 3. If the test has been passed:
     *       email certificate, 
     *       log test completion
     *       
     *  returns: The number of correct answers
     */
    public int saveGradeTest(Navigation navigation, TestData test, AuthenticatableUser authenticatableUser, User user) {

        int correct = test.gradeTest(user);

        Set<AnswerLog> log = test.getAnswerLog();

        for(AnswerLog l : log){
            l.setModule(navigation.getModule());
            genericDAO.save(l);
        }

        if(!navigation.getModule().isTestAnswersExist()){
            navigation.getModule().setTestAnswersExist(true);
            genericDAO.saveOrUpdate(navigation.getModule());
        }

        if(correct >= test.getNumberCorrectToPass())
        {
            //passed
            applicationContext.publishEvent(new SuccessTestCompletion(this, authenticatableUser, test, navigation, correct));
        }
        
        return correct;
    }
    
    private static String[] removeStrings = {"body", "html", "head", "title"};
    
    /**
     * build up a BlobFile from a string.  Parses the HTML data in the string.
     */
    public String parseHTMLBlobFile(String data, ResourceFacade resourceFacade, Long navigationId, boolean allowToolTips, boolean allowPageLinks, DataSqueezer dataSqueezer){

        String totalValue = null;

        if(data != null)
        {
            Tidy tidy = new Tidy();
            
            tidy.setMakeClean(false);
            //tidy.setShowWarnings(false);
            tidy.setTidyMark(false);
            tidy.setSmartIndent(false);
            tidy.setQuiet(true);
            
            //setup the linker 
            InputStream is = new ByteArrayInputStream(data.getBytes());
           
            DOMContentParser linker = new DOMContentParser(tidy.parseDOM(is, null), navigationId, allowToolTips, allowPageLinks, genericDAO, mediaService, dataSqueezer);
            
            //parse the nodes
            ByteArrayOutputStream os = new ByteArrayOutputStream();

            tidy.pprint(linker.linkNodes(), os);
            
            
            //set the referenced media/navigation
            resourceFacade.getReferencedResources().clear();
            for(ResourceReference ref : linker.getReferences()){
                ref.setResource(resourceFacade);
                resourceFacade.getReferencedResources().add(ref);
            }

            
            totalValue = os.toString();
            
            for(String removeString: removeStrings)
            {
                totalValue = totalValue.replaceFirst("<" + removeString + ">", "");
                totalValue = totalValue.replaceFirst("</" + removeString + ">", "");
            }
            
            totalValue = totalValue.replaceAll("http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0", "");
            totalValue = totalValue.replaceAll("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 3.2//EN\">", "");
            totalValue = totalValue.trim();
        
        }
        
        return totalValue;
    }
    
    public void setGenericDAO(HibernatePersistenceDAO genericDAO) {
        this.genericDAO = genericDAO;
    }

    public void setMediaService(MediaService mediaService) {
        this.mediaService = mediaService;
    }

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }
}
